package com.game.modular.game.battle.panel.attribute;

import com.game.comment.util.BeanUtil;
import com.game.modular.game.battle.panel.attribute.domain.EffectStatus;
import com.game.modular.game.battle.panel.attribute.domain.PlayerHeroAttribute;
import com.game.modular.game.playerAssets.domain.PlayerHero;
import com.game.modular.game.playerAssets.service.PlayerHeroServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;


/**
 * 武将属性面板
 *
 * @author cxy
 * @since 2024-08-23 19:46:19
 */
@Slf4j
@Validated
@Service
public class PlayerHeroAttributeServiceImpl extends PlayerHeroAttributeBaseServiceImpl {
    @Resource
    private PlayerHeroServiceImpl playerHeroServiceImpl;

    /**
     * 刷新武将兵力
     */
    public List<PlayerHero> refreshTroops(Long battleId, List<PlayerHero> actionList) {
        // 这里要排除npc
        Map<String, PlayerHeroAttribute> map = mapCache(battleId);
        Map<Long, Long> backLabel = map.values().stream()// 缓存数据(玩家+npc)
                .collect(Collectors.toMap(PlayerHeroAttribute::getId, PlayerHeroAttribute::getCurrentForce));
        return actionList.stream().peek(item -> item.setCurrentForce(backLabel.get(item.getId()))).collect(Collectors.toList());// 缓存刷新兵力(可能存在缓存不同步)
    }

    public void endRefreshTroops(Long battleId) {
        // 这里要排除npc
        Map<String, PlayerHeroAttribute> map = mapCache(battleId);
        Map<Long, Long> collect = map.values().stream()
                .filter(item -> item.getId() > 100)
                .collect(Collectors.toMap(PlayerHeroAttribute::getId, PlayerHeroAttribute::getCurrentForce));
        playerHeroServiceImpl.updateMilitaryStrength(collect);// 更新玩家信息
    }

    /**
     * 获取 属性
     */
    public PlayerHeroAttribute get(Long battleId, Long playerHeroId) {
        return (PlayerHeroAttribute) redisUtils.hGet(
                String.format(PlayerHeroAttribute_key, battleId),
                playerHeroId.toString()
        );
    }

    /**
     * 获取 基础属性
     */
    public PlayerHeroAttribute getBase(Long battleId, Long playerHeroId) {
        return (PlayerHeroAttribute) redisUtils.hGet(
                String.format(PlayerHeroAttribute_base_key, battleId),
                playerHeroId.toString()
        );
    }


    public double getBaseValue(Long battleId, Long targetPlayerHeroId, String changeFieldName) {
        PlayerHeroAttribute base = getBase(battleId, targetPlayerHeroId);
        return BeanUtil.getTargetValue(base, changeFieldName);
    }

    public double getValue(Long battleId, Long targetPlayerHeroId, String changeFieldName) {
        PlayerHeroAttribute base = get(battleId, targetPlayerHeroId);
        return BeanUtil.getTargetValue(base, changeFieldName);
    }

    public boolean statusUse(PlayerHeroAttribute attribute, long statusId) {
        Map<Long, EffectStatus> status = attribute.getStatus();
        EffectStatus confusion = status.get(statusId);
        if (confusion == null) {
            return false;
        }
        boolean use = confusion.use();
        status.put(statusId, confusion);
        attribute.setStatus(status);
        return use;
    }

    public boolean statusUseAndRefresh(PlayerHeroAttribute attribute, long statusId) {
        boolean use = statusUse(attribute, statusId);
        saveCache(attribute);
        return use;
    }

    public Set<Long> getDeadSet(Long battleId) {
        return listCache(battleId).stream()
                .filter(item -> item.getCurrentForce() <= 0)
                .mapToLong(PlayerHeroAttribute::getId)
                .boxed()
                .collect(Collectors.toSet());
    }

    public Map<Long, Long> getSurvivalMap(Long battleId) {
        return listCache(battleId).stream()
                .filter(item -> item.getCurrentForce() > 0)
                .collect(Collectors.toMap(PlayerHeroAttribute::getId, PlayerHeroAttribute::getCurrentForce));
    }

    public Map<Integer, List<PlayerHeroAttribute>> obtainBothSidesSurvivalHeroList(Long battleId) {
        return listCache(battleId).stream()
                .filter(item -> item.getCurrentForce() > 0)
                .collect(Collectors.groupingBy(PlayerHeroAttribute::getRankCamp));
    }
}
